<template>
	<view class="ReadBook">
		<!-- 阅读结束 -->
		<view v-if="status" class="ReadBook-status" >
			<view class="ReadBook-poster padding bg-white">
				<image style="width: 100%;height: 60vh;" :src="book.cover" mode="aspectFit">
				</image>
				<view class="padding-top text-center text-green">
					已读完
				</view>
			</view>
			<view class="ReadBook-btns margin flex">
				<view class="text-center">
					<button @click="copyFn" class="cu-btn lg bg-yellow text-white">再读一遍</button>
				</view>
				<view class="text-center">
					<button :disabled="!next" @click="nextFn" class="cu-btn lg bg-red">阅读下一本</button>
				</view>
			</view>
			<!-- ios兼容 -->
			<view class="ios-safe"></view>
		</view>
		<!-- 阅读中 -->
		<!-- 竖屏 -->
		<view v-else class="ReadBook-nostatus" v-else>
			<!-- 进度条 -->
			<view v-if="ac" class="ReadBook-progress padding-lr-xs">
				<view class="cu-progress round  xs">
					<view class="bg-red" :style="[{ width:progress}]"></view>
				</view>
			</view>
			<!-- 设置 -->
			<view v-if="device && type!='Audio'" class="flex justify-end margin">
				<image @click="openSettingFn" style="width: 50upx;height: 50upx;" src="@/static/read/setting.png" mode="scaleToFill"></image>
			</view>
			<!-- 阅读内容 -->
			<swiper  @change="swiperChangeFn" :current="swiperValue" :class="[device ? 'device-y margin' : 'device-x margin-lr margin-tb-xs']" class="ReadBook-swiper" :autoplay="false">
				<swiper-item v-for="(item,index) in swiperList" :key="item.id">
					<image :src="item.image" mode="aspectFill"></image>
					<!-- 翻译 -->
					<view  v-if="setting.translate && item.chinese  && type!='Audio'" class="y ReadBook-translate text-sm">
						{{item.chinese}}
					</view>
					<!-- 数目 -->
					<view class="y ReadBook-count text-sm">
						<view>{{(index+1)+'/'+swiperList.length}}</view>
					</view>
					<!-- 效果 -->
					<view  @click="handleSwiperFn(-1)" v-if="setting.effect==1 && index!=0  && type!='Audio'" class="y ReadBook-back">
						<text class="cuIcon-back text-white"></text>
					</view>
					<view @click="handleSwiperFn(1)" v-if="setting.effect==1 && index!=swiperList.length-1  && type!='Audio'"
						class="y ReadBook-right">
						<text class="cuIcon-right text-white"></text>
					</view>
				</swiper-item>
			</swiper>
			<!-- 功能 -->
			<view v-if="type!='Audio'" :class="[device ? 'margin' : 'ReadBook-func-y']" class="ReadBook-func flex align-center justify-between ">
				<!-- 设置 -->
				<view v-if="!device">
					 <image @click="openSettingFn"  src="@/static/read/setting.png" mode="scaleToFill"></image>
				</view>
				<!-- 收藏 -->
				<view @click="funcfn('collect')">
					<image v-if="func.collect" src="@/static/read/collect1.png" mode="aspectFill"></image>
					<image v-else src="@/static/read/collect.png" mode="aspectFill"></image>
				</view>
				<!-- 翻译 -->
				<view @click="funcfn('translate')">
					<image v-if="setting.translate" src="@/static/read/ce1.png" mode="aspectFill"></image>
					<image v-else src="@/static/read/ce.png" mode="aspectFill"></image>
				</view>
				<!-- 阅读方式 -->
				<view @click="funcfn('effect')">
					<image v-if="setting.effect===1" src="@/static/read/move.png" mode="aspectFill"></image>
					<image style="transform: scale(0.8);" v-else src="@/static/read/read.png" mode="aspectFill"></image>
				</view>
			</view>
			<!-- 控制器 -->
			<view :style="{height:device ? '100upx' : '0upx'}" v-if="swiperList[swiperValue]['audioFile']" class="ReadBook-control">
				<view :style="{height:device ? '100upx' : '60upx'}" :class="[device ? 'bg-white' : '']" class=" flex align-center">
					<view :class="device ? 'ReadBook-control-x' : 'ReadBook-control-y'" style="width: 100%;" class="padding-lr flex justify-between align-center padding-lr">
						<view v-if="type!='Audio'" @click="controlfn('no')">
							<!-- 播放 -->
						<image v-if="control.no" src="@/static/read/b.png" mode="aspectFill"></image>
						<image v-else src="@/static/read/d.png" mode="aspectFill"></image>
						</view>
						<view v-else></view>
						<view class="flex align-center">
							<view v-if="type!='Audio'" @click="controlfn('voice')" class="margin-right">
								<!-- 播放录音 -->
								<image v-if="control.voice" src="@/static/read/a.png" mode="aspectFill"></image>
								<image v-else src="@/static/read/c.png" mode="aspectFit"></image>
							</view>
							<view @click="controlfn('voiceno')">
								<!-- 播放录音 -->
							<image v-if="control.voiceno" src="@/static/read/b.png" mode="aspectFill"></image>
							<image v-else src="@/static/read/e.png" mode="scaleToFill"></image>
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>
		<!-- 设置 -->
		<view class="ReadBook-setting cu-modal" :class="showModal ?'show':''" @click="closeSettingFn">
			<view class="cu-dialog" @click.stop="">
				<view class="cu-list menu text-left">
					<!-- 横竖屏 -->
					<view class="cu-item arrow">
						<view class="flex-sub">横竖屏</view>
						<picker @change="(e)=>SettingFn('type',e.detail.value)" :value="setting.type" :range="picker">
							<view class="picker">
								{{picker[setting.type]}}
							</view>
						</picker>
					</view>
					<!-- 音频自动播放 -->
					<view class="cu-item">
						<view class="flex-sub">音频自动播放</view>
						<switch @change="(e)=>SettingFn('audio_auto',e.detail.value)"
							:class="setting.audio_auto?'checked':''" :checked="setting.audio_auto?true:false">
						</switch>
					</view>
					<!-- 自动阅读下一本 -->
					<view class="cu-item">
						<view class="flex-sub">自动阅读下一页</view>
						<switch @change="(e)=>SettingFn('read_auto',e.detail.value)"
							:class="setting.read_auto?'checked':''" :checked="setting.read_auto?true:false">
						</switch>
					</view>
					<!-- 查看翻译 -->
					<view class="cu-item">
						<view class="flex-sub">查看翻译</view>
						<switch @change="(e)=>SettingFn('translate',e.detail.value)"
							:class="setting.translate?'checked':''" :checked="setting.translate?true:false">
						</switch>
					</view>
					<!-- 翻页效果 -->
					<view class="cu-item arrow">
						<view class="flex-sub">翻页效果</view>
						<picker @change="(e)=>SettingFn('effect',e.detail.value)" :value="setting.effect"
							:range="effectPicker">
							<view class="picker">
								{{effectPicker[setting.effect]}}
							</view>
						</picker>
					</view>
					<!-- 播放速度 -->
					<view class="cu-item arrow">
						<view class="flex-sub">播放速度</view>
						<picker @change="(e)=>SettingFn('speed',e.detail.value)" :value="setting.speed"
							:range="speedPicker">
							<view class="picker">
								{{speedPicker[setting.speed]}}
							</view>
						</picker>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import * as api from '@/api/ReadBook/index.js'

	import audioControls from '@/utils/audio_controls.js';
	import recorderControls from '@/utils/recorder_controls.js';

	import Share from '@/utils/share.js';
	export default {
		mixins: [audioControls, recorderControls, Share],
		data() {
			return {
				type:'', // 仅针对录音页面
				device:true,
				id: null,
				book: {},
				next: null,
				// oos 
				oos: null,
				// 阅读状态
				status: false,
				// 进度条
				progress: '0%',
				// 阅读内容
				swiperValue: 0,
				swiperList: [],
				// 功能
				func: {
					collect: false,
				},
				// 控制器
				control: {
					no: false, // true 正在播放 false 暂停或者无
					voice: false,
					voiceno: false
				},
				// 设置
				showModal: false,
				setting: {
					type: 0,
					audio_auto: true,
					read_auto: true,
					translate: true,
					effect: 0,
					speed: 2
				},
				picker: ['自动识别', '固定横屏', '固定竖屏'],
				effectPicker: ['左滑', '无特效'],
				speedPicker: ['0.5x', '0.8x', '1.0x', '1.25x', '1.5x', '2.0x'],
				// 分享
				share: {
					title: '绘本',
					path: '/pages/ReadBook/index', // 全局分享的路径
					imageUrl: '', // 全局分享的图片(可本地可网络)
				},
				timer:null
			}
		},
		async onLoad(options) {
			this.getSettingFn();
			if (options.hasOwnProperty('id')) {
				this.id = options.id;
				if (options.hasOwnProperty('type')) {
					// 我的录音
					if (options.type == 'Audio' ) {
						this.type='Audio';
						await this.getSwiperList(true);
						this.swiperValue=options.page;
					} else {
						// 绘本
						this.getSwiperList();
					}
				} else {
					// 绘本
					this.getSwiperList();
				}
			}
		},
		onShow() {
			this.ac && this.ac.stop();
			if(this.status) this.ac=null;
			this.timer && clearInterval(this.timer);
		},
		onHide() {
			this.destroyFn();
		},
		onUnload() {
			this.destroyFn();
		},
		beforeDestroy() {
			this.destroyFn();
		},
		methods: {
			// 页面隐藏关闭销毁音频
			destroyFn(){
				this.ac && this.ac.stop();
				if(this.status) this.ac=null;
				uni.setPageOrientation({
					orientation: 'portrait'
				});
				this.timer && clearInterval(this.timer);
			},
			// 获取历史配置
			getSettingFn() {
				// 当前页面的永久配置
				let setting = uni.getStorageSync('_READBOOKSETTING');
				if (setting) {
					this.setting = JSON.parse(setting);
					this.closeSettingFn();
				}
				
			},
			// 打开设置
			openSettingFn() {
				this.showModal = true;
				uni.setPageOrientation({
					orientation: 'portrait'
				})
			},
			// 自动识别
			zdsbFn(){
				let orientation=this.book.orientation;
				uni.setPageOrientation({
					orientation: orientation==1 ?  'landscape' : 'portrait'
				})
			},
			// 关闭设置
			closeSettingFn() {
				this.showModal = false;
				switch (this.setting.type * 1) {
					case 0:
					     this.zdsbFn();
						break;
					case 1:
						uni.setPageOrientation({
							orientation: 'landscape'
						})
						break;
					default:
						uni.setPageOrientation({
							orientation: 'portrait'
						})
						break;
				}
			},
			// 上传到oss
			async oosFn(filePath) {
				let fileName = `${Date.now()+''+Math.floor(Math.random()*1000)}.mp3`;
				let res = await api.getDirectUploadToken(fileName);
				if (res.code === 0) {
					let {
						key,
						policy,
						ossAccessKeyId,
						signature,
						host
					} = res.data;
					await api.uploadFile(host, {
						filePath: filePath, // 录音返回文件地址。
						name: "file", //后台要绑定的名称
						formData: {
							key,
							policy,
							OSSAccessKeyId: ossAccessKeyId,
							success_action_status: '200',
							signature
						}
					})
					let url = host + '/' + key;
					let result = await api.recording(this.id, this.swiperValue, url);
					if (result.code === 0) {
						let item = this.swiperList[this.swiperValue];
						item['recording'] = url;
						this.$set(this.swiperList, this.swiperValue, item)
					}
				}
			},
			// 再次阅读
			copyFn() {
				this.swiperValue = 0;
				this.status = false;
				this.createAudioFn();
			},
			// 阅读下一本
			nextFn() {
				this.id = this.next.id;
				this.getSwiperList();
				this.status = false;
			},
			// 报错提示
			showModalFn(res) {
				uni.showModal({
					content: res.message,
					showCancel: false
				})
			},
			// 无特效
			handleSwiperFn(val) {
				this.swiperValue += val;
			},
			// 左右
			swiperChangeFn(e) {
				this.swiperValue = e.detail.current;
				// 如果正在录音
				if (this.control.voice) {
					//  暂停并上传录音
					this.rc && this.rc.stop();
				}
				// 切换逻辑
				if(this.type=='Audio'){
					this.controlfn('voiceno')
				}else{
					this.createAudioFn();
				}
				
			},
			/**
			 * 创建控件并配置信息
			 * @param {Object} Url  录音
			 * @param {Object} AudioAuto 播放当前
			 */
			createAudioFn(Url, AudioAuto) {
				let {
					audio_auto,
					speed,
					read_auto
				} = this.setting;
				if (this.status) return false;
				if (!Url) {
					if (this.swiperList.length == 0 || (this.swiperValue == this
							.swiperList.length - 1 && !this.swiperList[this.swiperValue]['audioFile'])) {
						this.ac && this.ac.stop();
						this.status = true;
						return;
					}
				}
				let url = Url ? Url : this.swiperList[this.swiperValue]['audioFile'];
				let type = !!Url; // 当前处理处理的逻辑枝 true 录音 false 绘本
				let playbackRate = this.speedPicker[speed].slice(0, -1) * 1;
				if (url) {
					this.acCreateControlsFn(url, {
						autoplay: AudioAuto || audio_auto,
						playbackRate,
						onPlay: () => {
							this.$set(this.control, type ? 'voiceno' : 'no', true);
						},
						onStop: () => {
							this.$set(this.control, type ? 'voiceno' : 'no', false);
						},
						onPause: () => {
							this.$set(this.control, type ? 'voiceno' : 'no', false);
						},
						onEnded: () => {
							this.progress='100%';
							if (type) {
								this.$set(this.control, type ? 'voiceno' : 'no', false);
							} else {
								// 阅读下一页
								if (read_auto) {
									this.swiperValue += 1;
								}
							}
						},
						onTimeUpdate: (currentTime, totalTime) => {
							this.progress = Math.floor((currentTime / totalTime) * 100, 2) + '%';
						}
					});
				}
			},
			/**
			 * 获取阅读内容  
			 * @param {Object} status true 禁止首先播放绘本
			 */
			async getSwiperList(status = false) {
				this.swiperValue = 0;
				let res = await api.read(this.id);
				if (res.code === 0) {
					let {
						book,
						next = null,
						pages,
						collected
					} = res.data;
					this.book = book;
					if(this.setting.type===0) this.zdsbFn();
					// 收藏状态
					this.$set(this.func, 'collect', collected);
					uni.setNavigationBarTitle({
						title: book.name
					});
					this.share = {
						title: book.name,
						path: `${this.share.path}?id=${this.id}`, // 全局分享的路径
						imageUrl: '', // 全局分享的图片(可本地可网络)
					}
					this.next = next;
					this.swiperList = pages;
					!status && this.createAudioFn();
				}
			},
			// 功能事件
			async funcfn(key) {
				switch (key) {
					case 'translate':
						// 翻译
						this.$set(this.setting, 'translate', !this.setting.translate);
						break;
					case 'effect':
						// 翻页效果
						this.$set(this.setting, 'effect', this.setting.effect === 0 ? 1 : 0);
						break;
					case 'collect':
						if (this.func.collect) {
							let res = await api.remove(this.id);
							if (res.code === 0) {
								this.$set(this.func, 'collect', false);
							}
						} else {
							let res = await api.collect(this.id);
							if (res.code === 0) {
								this.$set(this.func, 'collect', true);
							}
						}
						break;
					default:
						break;
				}
			},
			// 控制器事件
			controlfn(key) {
				// if (!this.ac) return false;
				switch (key) {
					case 'no':
						// 如果正在录音
						if (this.control.voice) {
							//  暂停并上传录音
							this.rc && this.rc.stop();
						}
						// 功能逻辑
						if (this.control['no']) {
							this.ac.stop();
						} else {
							this.createAudioFn('', true);
						}
						break;
					case 'voice':
						// 关闭播放
						this.ac && this.ac.stop();
						if (this.control['voice']) {
							//  暂停并上传录音
							this.rc && this.rc.stop();
							uni.showToast({
								title: "暂停录音",
								icon: 'none'
							})
						} else {
							uni.showToast({
								title: '当前正在录音',
								icon: 'none'
							})
							// 开始录音
							this.startRecorderFn();
						}
						break;
					case 'voiceno':
						if (this.control['voiceno']) {
							this.ac.stop();
						} else {
							// 播放录音
							console.log(123)
							// 如果正在录音，该功能无效
							if (this.control.voice) {
								//  暂停并上传录音
								this.rc && this.rc.stop();
								uni.showModal({
									content:"录音结束，播放录音",
									showCancel:false,
									success:()=>{
										// 解决录音上传的时差问题。
										if(this.timer) clearInterval(this.timer);
										this.timer=setInterval(()=>{
											if(!this.control.voice){
												clearInterval(this.timer);
												let recording = this.swiperList[this.swiperValue]['recording'];
												if (recording) {
													this.createAudioFn(recording,true);
												} else {
													this.showModalFn(new Error('当前无录音'))
												}
											}
										},300)
									}
								})
							}else{
								let recording = this.swiperList[this.swiperValue]['recording'];
								if (recording) {
									this.createAudioFn(recording,true);
								} else {
									this.showModalFn(new Error('当前无录音'))
								}
							}
						}
						break;
					default:
						break;
				}

			},
			// 开始录音
			startRecorderFn() {
				this.createRecorderFn({
					onStart: () => {
						this.$set(this.control, 'voice', true);
					},
					onStop: async (res) => {
						await this.oosFn(res.tempFilePath);
						this.$set(this.control, 'voice', false);
					}
				});
			},
			// 设置功能
			SettingFn(key, value) {
				this.$set(this.setting, key, value);
				// 自动读下一页
				if (key == "read_auto" || key == "audio_auto" || key=='speed') this.createAudioFn();
			},
			async markRead(){
				await api.markRead(this.id)
			}
			
		},
		onResize(res) {
			// 设备方向
			let {screenHeight,screenWidth}=res.size;
			this.device=screenHeight>screenWidth
		},
		watch: {
			status(newVal){
				if(newVal) {
					this.destroyFn();
					this.markRead()
				}
			},
			setting: {
				handler(newVal, oldVal) {
					let setting = JSON.stringify(newVal);
					uni.setStorageSync('_READBOOKSETTING', setting);
				},
				deep: true,
			},
			swiperValue(newVal, oldVal) {
				if (newVal >= this.swiperList.length) {
					this.ac && this.ac.stop();
					this.status = true;
					return;
				}else{
					this.status=false;
				}
			}
		}
	}
</script>

<style lang="scss">
	.ReadBook {
		 position: relative;
		.ReadBook-status {
			.ReadBook-poster {
				width: 90vw;
				margin: 30upx auto;
			}

			.ReadBook-btns {
				view {
					flex: 1;
				}
			}
		}

		.ReadBook-nostatus {
			.ReadBook-progress {
				position: fixed;
				z-index: 100;
				top: 0;
				left: 0;
				width: 100vw;
				box-sizing: border-box;

				>view {
					display: block;
				}
				
			}
            .device-y{
				height: 70vh;
			}
			.device-x{
				padding: 0 20vw;
				height: calc(100vh - 20upx);
				height:  calc(100vh - 20upx - constant(safe-area-inset-bottom));
				height:  calc(100vh - 20upx - env(safe-area-inset-bottom));
				.y{
					transform: scale(0.5);
				}
			}
			.ReadBook-swiper {
				position: relative;

				swiper-item {
					width: 100%;
					height: 100%;
					position: relative;

					image {
						width: 100%;
						height: 100%;
					}

					.ReadBook-translate {
						position: absolute;
						top: 5upx;
						left: 10%;
						padding: 10upx 10upx;
						word-break: break-all;
						white-space: normal;
						width: 80%;
						box-sizing: border-box;
						background-color: rgba(0, 0, 0, 0.8);
						color: #fff;
						text-align: center;
					}

					.ReadBook-count {
						position: absolute;
						display: flex;
						align-items: center;
						justify-content: center;
						bottom: 5upx;
						left: 0;
						width: 100%;
						height: 50upx;

						>view {
							padding: 2upx 20upx;
							border-radius: 20upx;
							box-sizing: border-box;
							background-color: rgba(0, 0, 0, 0.8);
							color: #fff;
						}
					}

					.ReadBook-back,
					.ReadBook-right {
						width: 100upx;
						height: 100upx;
						position: absolute;
						top: calc(50% - 50upx);
						display: flex;
						align-items: center;
						justify-content: center;
						background-color: rgba(0, 0, 0, 0.5);
						border-radius: 20upx;
					}

					.ReadBook-back {
						left: 5upx;
					}

					.ReadBook-right {
						right: 5upx;
					}

				}

			}

			.ReadBook-func {
				>view {
					width: 40upx;
					height: 40upx;
                   
					image {
						width: 100%;
						height: 100%;
					}
				}
			}
			.ReadBook-func-y{
				position: absolute;
				width: 40upx;
				height: calc(100vh - 60upx);
				height:  calc(100vh - 60upx - constant(safe-area-inset-bottom));
				height:  calc(100vh - 60upx - env(safe-area-inset-bottom));
				top: 0;
				right: 26upx;
				flex-direction: column;
				box-sizing: border-box;
				padding: 10upx 0;
				>view{
					width: 20upx;
					height: 20upx;
				}
			}

			.ReadBook-control {
				padding-bottom: constant(safe-area-inset-bottom);
				padding-bottom: env(safe-area-inset-bottom);
				box-sizing: content-box;
			

				>view {
					position: fixed;
					bottom: 0;
					left: 0;
					width: 100%;
					box-sizing: content-box;
					padding-bottom: constant(safe-area-inset-bottom);
					padding-bottom: env(safe-area-inset-bottom);
				}
				.ReadBook-control-x{
					image{
						width: 50upx;
						height: 50upx;
					}
				}
				.ReadBook-control-y{
					image{
						width: 30upx;
						height: 30upx;
					}
				}
			}
		}

		.ReadBook-setting {
			padding-bottom: constant(safe-area-inset-bottom);
			padding-bottom: env(safe-area-inset-bottom);
			box-sizing: content-box;

			&::after {
				content: "";
				display: block;
				padding-bottom: constant(safe-area-inset-bottom);
				padding-bottom: env(safe-area-inset-bottom);
				position: absolute;
				bottom: 0;
				left: 0;
				width: 100vw;
				background-color: #fff;
			}
		}
	}
</style>